package cloud.xlh.digital_power_order.config.rabbitmq;

import cloud.xlh.infrastructure.mq.operate.BaseMQOperateParamIn;
import cloud.xlh.infrastructure.mq.operate.BaseMQOperateParamOut;
import cloud.xlh.infrastructure.mq.operate.MQOperateService;
import cloud.xlh.infrastructure.mq.operate.MQSendMessageFunctionInterface;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 *
 * @ project name : xlh_osms
 * @ Author: XuLeHuang
 * @ Date: 2023/10/12 10:42
 * @ Description:
 */
@Service(value = "rabbitMQOperateService")
public class RabbitMQOperateService implements MQOperateService {
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Override
        public BaseMQOperateParamOut sendMessagePostHandle(BaseMQOperateParamOut baseMQOperateParamOut) {
        RabbitMQOperateParamOut rabbitMQOperateParamOut = (RabbitMQOperateParamOut) baseMQOperateParamOut;
        RabbitMQOperateParamIn rabbitMQOperateParamIn = (RabbitMQOperateParamIn) rabbitMQOperateParamOut.getPreHandleResult();
        Map diyData = (Map)rabbitMQOperateParamIn.getDiyData();
        diyData.put("status" , "000000");
        return rabbitMQOperateParamOut;
    }


    @Override
    public BaseMQOperateParamOut sendMessagePreHandle(BaseMQOperateParamIn baseMQOperateParamIn , BaseMQOperateParamOut baseMQOperateParamOut) {
        RabbitMQOperateParamIn rabbitMQOperateParamIn = (RabbitMQOperateParamIn) baseMQOperateParamIn;
        Map diyData = (Map)rabbitMQOperateParamIn.getDiyData();
        String exchange = (String)diyData.get("exchange");
        String routingKey = (String)diyData.get("routingKey");
        String message = (String)diyData.get("message");
        rabbitMQOperateParamIn.setExchange(exchange);
        rabbitMQOperateParamIn.setRoutingKey(routingKey);
        rabbitMQOperateParamIn.setMessage(MessageBuilder.withBody(message.getBytes(StandardCharsets.UTF_8)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).build());
        RabbitMQOperateParamOut rabbitMQOperateParamOut = (RabbitMQOperateParamOut) baseMQOperateParamOut;
        rabbitMQOperateParamOut.setPreHandleResult(rabbitMQOperateParamIn);
        return rabbitMQOperateParamOut;
    }

    public BaseMQOperateParamIn buildMQOperateParamIn(Map<String , String> paramInMap) {
        BaseMQOperateParamIn<Map<String , String>> mqOperateParamIn = new RabbitMQOperateParamIn();
        mqOperateParamIn.setMqSendMessageFunctionInterface(new MQSendMessageFunctionInterface<RabbitMQOperateParamOut , RabbitMQOperateParamIn>() {
            @Override
            public RabbitMQOperateParamOut sendMessage(RabbitMQOperateParamIn in , RabbitMQOperateParamOut out) {
                rabbitTemplate.convertAndSend(in.getExchange() , in.getRoutingKey() , in.getMessage() ,
                        new MessagePostProcessor() {
                            @Override
                            public Message postProcessMessage(Message message) throws AmqpException {
                                MessageProperties messageProperties = message.getMessageProperties();
                                //15分钟过期
                                Map<String, String> diyData = (Map) in.getDiyData();
                                messageProperties.setExpiration(diyData.get("ttl"));
                                //设置持久化
                                messageProperties.setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);
                                return message;
                            }
                        });
                rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
                    @Override
                    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                       /* String id = correlationData.getId();
                        ReturnedMessage returned = correlationData.getReturned();
                        if (!ack) {
                            //todo 出错处理
                        }*/
                    }
                });
                //设置路由失败回调方法
                rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
                    @Override
                    public void returnedMessage(ReturnedMessage returnedMessage) {
                        Message message = returnedMessage.getMessage();
                        int replyCode = returnedMessage.getReplyCode();
                        String replyText = returnedMessage.getReplyText();
                        String routingKey = returnedMessage.getRoutingKey();
                        String exchange = returnedMessage.getExchange();
                    }
                });
                return out;
            }
        });
        mqOperateParamIn.setDiyData(paramInMap);
        return mqOperateParamIn;
    }
    public void process(Map<String , String> paramInMap) {
        BaseMQOperateParamIn mqOperateParamIn = buildMQOperateParamIn(paramInMap);
        BaseMQOperateParamOut<Map ,Map ,Map> mqOperateParamOut = new RabbitMQOperateParamOut();
        mqOperateParamOut = (RabbitMQOperateParamOut)sendMessage(mqOperateParamIn , mqOperateParamOut);
    }
}
